﻿Imports System.Drawing.Drawing2D

Public Class GWaveToolbar
    Private m_menuItems As List(Of GWaveMenuItem)

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

        m_menuItems = New List(Of GWaveMenuItem)()

        'Reduce flicker by enabling double buffer and resize redraw.
        MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw, True)
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        'Add your custom paint code here

        With e.Graphics
            'Draw background border.
            Using backgroundBorder As Pen = New Pen(Color.FromArgb(170, 170, 170), 1)
                .DrawRectangle(backgroundBorder, New Rectangle(0, 0, Me.Width - 1, Me.Height - 1))
            End Using

            'Main Gradient Background All space (except for border which surrounds 1 pixel thickness)
            Using backgroundBrush As Brush = New LinearGradientBrush(New Point(0, 1), New Point(0, 23), Color.White, Color.FromArgb(221, 221, 221))
                .FillRectangle(backgroundBrush, New Rectangle(1, 1, Me.Width - 2, Me.Height - 2))
            End Using

            If m_menuItems.Count > 0 Then
                Dim xpos As Integer = 1 'Only within outer border.

                'TODO: Is this font correct?
                'Note that after updating this font the layout code will
                'automatically compensate for any layout changes.
                Dim fnt As Font = New Font(New FontFamily("Arial"), 11, FontStyle.Regular, GraphicsUnit.Pixel)

                Dim splitterTopMidBrush As LinearGradientBrush = New LinearGradientBrush(New Point(0, 1), New Point(0, 12), Color.FromArgb(251, 251, 251), Color.FromArgb(171, 171, 171))
                Dim splitterMidBtmBrush As LinearGradientBrush = New LinearGradientBrush(New Point(0, 11), New Point(0, 22), Color.FromArgb(171, 171, 171), Color.FromArgb(221, 221, 221))

                Dim i As Integer
                'We need index as well as item so use standard for loop.
                For i = 0 To m_menuItems.Count - 1
                    Dim item As GWaveMenuItem = m_menuItems.Item(i)

                    Dim txt_size As SizeF = .MeasureString(item.Header, fnt, Me.Width - (xpos + 1))
                    Dim item_width As Integer = txt_size.Width + 8 + 16 + 8

                    If i + 1 = m_menuItems.Count Then
                        If (Me.Width - xpos) < item_width Then
                            Exit For
                        End If
                    Else
                        'Guarrentee enough space for elipises for next menu item.
                        If (Me.Width - xpos) < (item_width + 20) Then
                            Exit For
                        End If
                    End If


                    If i > 0 Then
                        .FillRectangle(splitterTopMidBrush, New Rectangle(xpos, 1, 1, 11))
                        .FillRectangle(splitterMidBtmBrush, New Rectangle(xpos, 12, 1, 10))
                    End If

                    .DrawString(item.Header, fnt, Brushes.Black, xpos + 8 + 16, (Me.Height - txt_size.Height) \ 2)

                    xpos += item_width + 1
                Next

                splitterTopMidBrush.Dispose()
                splitterMidBtmBrush.Dispose()

                If i + 1 < m_menuItems.Count Then
                    'Draw Elipses
                    xpos = Me.Width - (20 + 1)

                    Using downlineBorder As Pen = New Pen(Color.FromArgb(170, 170, 170), 1)
                        .DrawLine(downlineBorder, xpos, 0, xpos, Me.Height)
                    End Using

                    Using blackBoxBrush As SolidBrush = New SolidBrush(Color.FromArgb(102, 102, 102)), whiteBoxBrush As SolidBrush = New SolidBrush(Color.FromArgb(248, 248, 248))
                        .FillRectangle(whiteBoxBrush, New Rectangle(xpos + 6, 13, 2, 2))
                        .FillRectangle(blackBoxBrush, New Rectangle(xpos + 5, 12, 2, 2))

                        .FillRectangle(whiteBoxBrush, New Rectangle(xpos + 6 + 4, 13, 2, 2))
                        .FillRectangle(blackBoxBrush, New Rectangle(xpos + 5 + 4, 12, 2, 2))

                        .FillRectangle(whiteBoxBrush, New Rectangle(xpos + 6 + 8, 13, 2, 2))
                        .FillRectangle(blackBoxBrush, New Rectangle(xpos + 5 + 8, 12, 2, 2))
                    End Using
                End If
            End If
        End With
    End Sub

    Private Sub GWaveToolbar_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        UpdateSize()
    End Sub

    'Not nessasary just called on Resize event (todo: on init etc)
    Private Sub UpdateSize()
        If Me.Height <> 24 Then Me.Height = 24
    End Sub

    Public Sub ClearMenuItems()
        m_menuItems.Clear()
        Me.Refresh()
    End Sub

    Public Sub AddMenuItem(ByVal item As GWaveMenuItem)
        If Not m_menuItems.Contains(item) Then
            m_menuItems.Add(item)
        Else
            Throw New Exception("Item already added to this GWaveToolbar.")
        End If

        Me.Refresh()
    End Sub

    Public Sub RemoveMenuItem(ByVal item As GWaveMenuItem)
        m_menuItems.Remove(item)

        Me.Refresh()
    End Sub
End Class
